package com.zd.controller;

import com.cloopen.rest.sdk.CCPRestSmsSDK;
import com.zd.config.MinioConfig;
import com.zd.domain.Course;
import com.zd.domain.Result;
import com.zd.domain.User;
import com.zd.service.MinioService;
import com.zd.service.SmsService;
import com.zd.service.user.UserService;
import com.zd.utils.JWTUtils;
import io.minio.errors.*;
import jakarta.annotation.Resource;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Part;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Map;

@CrossOrigin
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private MinioService minioService;

    @Resource
    @Autowired
    private MinioConfig minioConfig;

    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 登录
     *
     * @param username
     * @param userPassword
     * @return
     */

    @CrossOrigin
    @GetMapping("/login")
    public Result<User> login(@RequestParam(value = "username", required = false, defaultValue = "0") String username,
                              @RequestParam(value = "userPassword", required = false, defaultValue = "0") String userPassword) {

        System.out.println(username);
        System.out.println(userPassword);


        User user = userService.login(username, userPassword);



        Result<User> result = new Result<>();

        if (user == null) {
            result.setCode(400);
            result.setMsg("登录失败！");
        } else {
            user.setUserKey(null);
            user.setUserPassword(null);
            result.setCode(200);
            result.setMsg("登录成功！");
            result.setData(user);
        }

        return result;
    }

    /**
     * 注册
     *
     * @param user
     * @return
     */
    @PostMapping("/register")
    public Result<Integer> register(@RequestBody User user) {

        int i = userService.register(user);

        Result<Integer> result = new Result<>();

        if (i == 1) {
            result.setCode(201);
            result.setMsg("注册成功！");
            result.setData(i);
        } else {
            result.setCode(401);
            result.setMsg("注册失败！");
        }

        return result;

    }

    @PutMapping("/upassword")
    public Result<Integer> updatePassword(@RequestParam("username") String username,
                                          @RequestParam("oldUserPassword") String oldUserPassword,
                                          @RequestParam("newUserPassword") String newUserPassword) {

        int i = userService.updatePassword(username, oldUserPassword, newUserPassword);

        Result<Integer> result = new Result<>();

        if (i == 1) {
            result.setCode(203);
            result.setMsg("修改密码成功！");
            result.setData(i);
        } else {
            result.setCode(403);
            result.setMsg("修改密码失败！");
        }

        return result;
    }

    /**
     * 修改用户绑定的手机号
     *
     * @param username
     * @param phone
     * @return
     */
    @CrossOrigin
    @PutMapping("/uphone")
    public Result<Integer> updatePhone(@RequestParam("username") String username,
                                       @RequestParam("phone") String phone,
                                       @RequestParam("inputCode") String inputCode) {
        Result<Integer> result = new Result<>();
        int i = 0;
        //查询这个手机号是否被绑定
        User user = userService.findByPhone(phone);

        if (user == null) {

            //检验手机验证码
            Map<String, Object> map = (Map<String, Object>) redisTemplate.boundValueOps(phone).get();

            if (map != null) {
                String codeStr = (String) map.get("codeStr");

                SmsService smsService = new SmsService();

                if (codeStr != null) {

                    boolean isTrue = smsService.verifyCode(inputCode, codeStr);

                    if (isTrue) {

                        i = userService.updatePhone(username, phone);

                    }
                }
            }
            if (i == 1) {
                result.setCode(204);
                result.setMsg("修改绑定的手机号成功！");
                result.setData(i);
            } else {
                result.setCode(404);
                result.setMsg("修改绑定的手机号失败！");
            }
        } else {
            result.setCode(405);
            result.setMsg("该手机号已被绑定！");
        }

        return result;

    }

    @GetMapping("/phoneLogin")
    public Result<User> phoneLogin(@RequestParam("phone") String phone,
                                   @RequestParam("inputCode") String inputCode) {
        System.out.println(phone);
        System.out.println(inputCode);
        Result<User> result = new Result<>();
        //根据手机号查用户
        User user = userService.findByPhone(phone);

        if (user != null) {

            Map<String, Object> map = (Map<String, Object>) redisTemplate.boundValueOps(phone).get();

            if (map != null) {

                String codeStr = (String) map.get("codeStr");

                SmsService smsService = new SmsService();

                if (codeStr != null) {

                    //验证验证码
                    boolean isTrue = smsService.verifyCode(inputCode, codeStr);

                    //正确
                    if (isTrue) {

                        //添加token
                        //用户名和密码输入正确后，创建token，并将coken存入user中，当token过滤器在过滤时，可以拿到这两个token进行是否放行操作
                        String token = JWTUtils.createJWT(1000 * 60 * 30, user.getId());

                        String longToken = JWTUtils.createJWT(1000 * 60 * 60 * 24 * 7, user.getId());

                        user.setToken(token);
                        user.setLongToken(longToken);


                        //登录成功！
                        result.setCode(206);
                        result.setMsg("手机验证登录成功！");
                        result.setData(user);

                    } else {
                        result.setCode(406);
                        result.setMsg("验证码有误！");
                    }
                } else {
                    result.setCode(407);
                    result.setMsg("未获取到验证码！");
                }

            } else {
                result.setCode(408);
                result.setMsg("手机号与验证码不匹配！");
            }

        } else {
            result.setCode(409);
            result.setMsg("用户不存在！");
        }
        return result;
    }

    @GetMapping("/list")
    public List<User> list() {
        List<User> list = userService.list();


        return list;
    }

    /**
     * 修改用户信息（头像）
     * @param file
     * @param userId
     * @return
     */
    @CrossOrigin
    @PostMapping("/updateUserImg")
    public Result<User> updateUserImg(@RequestPart("file") MultipartFile file,
                                        @RequestParam("userId") int userId) {

        System.out.println(file);
        String avatarUrl = null;
        Result<User> result = new Result<>();
        //判断用户是否上传照片，有的话进行头像上传，没有的话只进行其他信息的修改

        //修改全部信息
        try {
            //上传文件返回网络地址
            avatarUrl = minioService.uploadFile(minioConfig.getBucketName(), file);

        } catch (Exception e) {

            throw new RuntimeException(e);
        }
        User user = new User();
        user.setId(userId);
        user.setAvatar(avatarUrl);
        int influenceRows = userService.updateUserImg(user);
        if (influenceRows == 1){
            //再去查找一次
            User findUser = userService.findByUserID(userId);
            result.setCode(200);
            result.setMsg("修改成功");
            result.setData(findUser);
        }else {
            result.setCode(411);
            result.setMsg("修改失败");
        }
        return result;
    }

    /**
     * 修改用户信息（性别，昵称）
     * @param sex
     * @param nickname
     * @param userId
     * @return
     */
    @CrossOrigin
    @GetMapping("/updateUserInfo")
    public Result<User> updateUserInfo(@RequestParam("sex") String sex,
                                       @RequestParam("nickname") String nickname,
                                      @RequestParam("userId") int userId) {
        Result<User> result = new Result<>();
        //修改全部信息
        User user = new User();
        user.setSex(sex);
        user.setNickname(nickname);
        user.setId(userId);
        int influenceRows = userService.updateUserInfo(user);
        if (influenceRows == 1){
            //再去查找一次
            User findUser = userService.findByUserID(userId);
            result.setCode(200);
            result.setMsg("修改成功");
            result.setData(findUser);
        }else {
            result.setCode(411);
            result.setMsg("修改失败");
        }
        return result;
    }

    @GetMapping("/{id}")
    public Result<User> findByUserID(@PathVariable("id") int id) {

        User user = userService.findByUserID(id);

        Result<User> result = new Result<>();

        if (user != null) {
            result.setCode(2001);
            result.setMsg("查询用户成功！");
            result.setData(user);
        } else {
            result.setCode(4001);
            result.setMsg("查询用户失败！");
        }

        return result;
    }


    @CrossOrigin
    @GetMapping("findPhone")
    public Result findPhone(@RequestParam("phone") String phone) {
        Result result = new Result();
        User user = userService.findByPhone(phone);
        if (user != null) {
            //该手机号存在
            result.setCode(200);
            result.setMsg("手机号存在");
        } else {
            result.setCode(411);
            result.setMsg("手机号不存在");
        }
        return result;
    }


    /**
     * 忘记密码
     *
     * @param user
     * @return
     */
    @CrossOrigin
    @PutMapping("/updatePsd")
    public Result updatePsd(@RequestBody User user) {
        Result result1 = new Result();
        int influenceRows = userService.updatePsd(user);
        if (influenceRows == 1) {
            result1.setCode(200);
            result1.setMsg("修改成功");
        } else {
            result1.setCode(411);
            result1.setMsg("修改失败");
        }
        return result1;
    }


    //查询用户原密码
    @GetMapping("/findOldPassword")
    public Result findOldPassword(@RequestParam("username") String username,
                                  @RequestParam("oldUserPassword") String oldUserPassword) {

        boolean isTrue = userService.findOldPassword(username, oldUserPassword);

        Result result = new Result();

        if (isTrue) {
            result.setCode(200);
            result.setMsg("输入的原密码正确！");
        } else {
            result.setCode(400);
            result.setMsg("原密码错误！");
        }
        return result;
    }


}
